home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / C / Applications / Telnet 2.7b5 / source / FTPserver / binsubs.c next >
Encoding:
C/C++ Source or Header  |  1995-04-01  |  11.2 KB  |  461 lines  |  [TEXT/CWIE]

  1. /****************************************************************
  2. *    NCSA Telnet for the Macintosh                                *
  3. *                                                                *
  4. *    National Center for Supercomputing Applications                *
  5. *    Software Development Group                                    *
  6. *    152 Computing Applications Building                            *
  7. *    605 E. Springfield Ave.                                        *
  8. *    Champaign, IL  61820                                        *
  9. *                                                                *
  10. *    Copyright (c) 1986-1993,                                    *
  11. *    Board of Trustees of the University of Illinois                *
  12. *****************************************************************
  13. *    MacBinary Subroutines.    
  14. */
  15.  
  16. #ifdef MPW
  17. #pragma segment FTPServer
  18. #endif
  19.  
  20. #include "maclook.proto.h"
  21. #include "bkgr.proto.h"
  22. #include "MacBinary.h"
  23. #include "telneterrors.h"
  24. #include "binsubs.proto.h"
  25. #include "translate.proto.h"
  26. #include "debug.h"
  27. #include "DlogUtils.proto.h"    // For WriteZero
  28.  
  29. static    unsigned short    CalculateCRC(unsigned char *ptr, short count, unsigned short crc);
  30. static    void SetFileInfo(short volume, long dirID, StringPtr name, HFileParam *iop);
  31. static    void MakeTextFile(short volume, long dirID, StringPtr name, HFileParam *iop);
  32. static    short isMacBinary(MBHead *p);
  33. static    OSErr bwrite( MBFile *out, char *buffer, long size);
  34. static    void ProcessMBHead (MBFile *out, MBHead *header);
  35.  
  36. extern    MBFile        /* BYU */
  37.     *mbfp;            /* BYU */
  38.  
  39. #define BLOCKS(x)    ((x+127)/128)
  40. /*#define lmove(f,t)    memmove(f,t,(size_t) 4)        /* BYU LSC */
  41.  
  42. MBHead    *mbh;
  43. char    buffer[128];
  44.  
  45. unsigned short    CalculateCRC(unsigned char *ptr, short count, unsigned short crc)
  46. {
  47.     unsigned short    i;
  48.     
  49.     crc = 0;
  50.     while (count -- > 0) {
  51.         crc = crc ^ (unsigned short)*ptr++ << 8;
  52.         for (i = 0; i < 8; i++)
  53.             if (crc & 0x8000)
  54.                 crc = crc << 1 ^ 0x1021;
  55.             else
  56.                 crc = crc << 1;
  57.     }
  58.     
  59.     return crc;
  60. }
  61.  
  62. void GetFileInfo(short volume, long dirID, StringPtr name, HFileParam *iop)
  63. {
  64.     OSErr err;
  65.     iop->ioNamePtr = name;
  66.     iop->ioVRefNum = volume;
  67.     iop->ioDirID = dirID;
  68.     iop->ioFVersNum = 0;
  69.     iop->ioFDirIndex = 0;
  70.     err = PBHGetFInfo((HParmBlkPtr) iop, FALSE);
  71. }
  72.  
  73. void SetFileInfo(short volume, long dirID, StringPtr name, HFileParam *iop)
  74. {
  75.     OSErr err;
  76.     iop->ioNamePtr = name;
  77.     iop->ioVRefNum = volume;
  78.     iop->ioDirID = dirID;
  79.     iop->ioFVersNum = 0;
  80.     iop->ioFDirIndex = 0;
  81.     err = PBHSetFInfo((HParmBlkPtr) iop, FALSE);
  82. }
  83.  
  84. void MakeTextFile(short volume, long dirID, StringPtr name, HFileParam *iop)
  85. {
  86.     GetFileInfo(volume, dirID, name, iop);
  87.     iop->ioFlFndrInfo.fdType = 'TEXT';
  88.     iop->ioFlFndrInfo.fdCreator = gFTPServerPrefs->TextCreator;
  89.     SetFileInfo(volume, dirID, name, iop);
  90. }
  91.  
  92. short isMacBinary(MBHead *p)
  93. {
  94.     unsigned short    crc;
  95.     
  96.     if ((p->nlen > 0)   &&    (p->nlen < 65)  &&
  97.         (p->zero1 == 0) &&    (p->zero2 == 0) && (p->zero3 == 0))    {    // Assume MB I
  98.             crc = CalculateCRC((unsigned char *)p, 124, 0);
  99.             if (((short)p->crc == crc) && (p->mb2versnum > 128))    {        // Check for MB II
  100.                 if (p->mb2minvers > 129)
  101.                     return(0);            // If vers is greater than 129, leave it alone
  102.                 
  103.                 return (1);                // Valid MB II file.
  104.             }
  105.             else {            
  106.                 p->flags2 = 0;            // So we can use same routines for MB I & II
  107.                 return (1);                // Valid MB I file (we make it a II file on the fly.)
  108.                 }
  109.         }
  110.  
  111.     return(0);                            // Not a Macbinary file            
  112. }
  113.  
  114. long MBsize( MBFile *mbfp)
  115. {
  116.     long size = 0;
  117.     OSErr ret;
  118.     
  119.     ret = GetEOF( mbfp->fd, &size );            /* length of file data fork */
  120.     if (ret != noErr) 
  121.         size = 0;
  122.  
  123.     return(size);
  124. }
  125.  
  126. MBFile *MBopen(char *file, short vrefnum, long dirID, short mode)
  127. {
  128.     MBFile *mbfp;
  129.     OSErr err;
  130.     int i;
  131.     
  132.     if ((mbfp = (MBFile *) myNewPtr(sizeof(MBFile))) == NULL)
  133.         return(NULL);
  134.  
  135.     if (gFTPServerPrefs->DoISOtranslation)                // MP: translation method
  136.         trbuf_ftp_mac((unsigned char *)file, strlen(file));
  137.  
  138.     BlockMove(file, mbfp->name, 32);
  139.     if (strlen(file) > 31)
  140.         mbfp->name[31] = 0;
  141.  
  142.     c2pstr((char *)mbfp->name);
  143.  
  144.     if (mbfp->name[1] == '.') mbfp->name[1] = '_'; //replace leading period with slash
  145.  
  146.     for (i = 1; i <= mbfp->name[0]; i++)        // replace embedded slashes, colons, and CRs
  147.         if (mbfp->name[i] == '/' || mbfp->name[i] == ':' || mbfp->name[i] == CR) 
  148.             mbfp->name[i] = ' ';
  149.  
  150.     if (gFTPServerPrefs->DoISOtranslation)
  151.         trbuf_mac_ftp((unsigned char *)file, strlen(file));                // MP: translation method
  152.  
  153.  
  154.     mbfp->vrefnum = vrefnum;
  155.     mbfp->dirID = dirID;
  156.     mbfp->mode = mode;
  157.  
  158.     if ((err = HOpen( vrefnum, dirID, mbfp->name, fsRdWrPerm, &mbfp->fd)) != noErr) {
  159.         if ((err==-43) && (mode & MB_WRITE)) {
  160.             err = HCreate( vrefnum, dirID, mbfp->name, gFTPServerPrefs->BinaryCreator,
  161.                         gFTPServerPrefs->BinaryType);
  162.             if (mode & MB_ISASCII)    {
  163.                 HFileParam blah;
  164.                 MakeTextFile(vrefnum, dirID, mbfp->name, &blah);
  165.                 }
  166.                 
  167.             if (HOpen( vrefnum, dirID, mbfp->name, fsRdWrPerm, &mbfp->fd)) 
  168.                 return( 0L);
  169.             }
  170.         else 
  171.             return(0L);
  172.         }
  173.  
  174.     if (mode & MB_APPEND)
  175.         SetFPos(mbfp->fd,fsFromLEOF,0);
  176.  
  177.     mbfp->binary=0;
  178.     mbfp->sector1=1;
  179.     mbfp->fork=0;
  180.     return( mbfp);
  181. }
  182.  
  183. OSErr bwrite( MBFile *out, char *buffer, long size)
  184. {
  185.     long len = size;
  186.     OSErr error = noErr;
  187.  
  188.     if (out->binary) {
  189.         if (out->bytes > 0) {
  190.             if (out->bytes < len) len = out->bytes;
  191.             error= FSWrite( out->fd, &len, buffer);
  192.             out->bytes -= len;
  193.             buffer +=len;
  194.             size -= len;
  195.             }
  196.         if (out->bytes <= 0) {
  197.             if (!out->fork) {
  198.                 out->fork = 1;
  199.                 out->bytes = BLOCKS(out->rlen)*128;
  200.                 SetEOF( out->fd, (long) out->dlen);
  201.                 FSClose( out->fd);
  202.                 if (out->bytes) {
  203.                     HOpenRF( out->vrefnum, out->dirID, out->name, fsRdWrPerm, &out->fd);
  204.                     if (size) {
  205.                         len = (long) size;
  206.                         error= FSWrite( out->fd, &len, buffer);
  207.                         }
  208.                     }
  209.                 else
  210.                     out->fd = 0;
  211.                 }
  212.             else SetEOF( out->fd, (long) out->rlen);
  213.             }
  214.         }
  215.     else {
  216.         error = FSWrite( out->fd, &len, buffer);
  217.         }
  218.     return (error);
  219. }
  220.  
  221. void ProcessMBHead (MBFile *out, MBHead *header)
  222. {
  223.     OSErr    err;
  224.  
  225.     BlockMove(header, &out->header, sizeof(MBHead));
  226.     out->binary = 1;
  227.     BlockMove(&header->dflen[0], &out->dlen, 4);
  228.     BlockMove(&header->rflen[0], &out->rlen, 4);
  229.     out->bytes = BLOCKS(out->dlen)*128;
  230.     out->fork = 0;
  231.     out->sector1 = 0;
  232.  
  233.     FSClose(out->fd);
  234.     if (HDelete( out->vrefnum, out->dirID, out->name))            /* Error deleting Old File */
  235.         DoError (200 | RESOURCE_ERRORCLASS, LEVEL1, NULL);
  236.         
  237.     BlockMove(&out->header.nlen, out->name, 32);
  238.  
  239. #if 0                                                            /* BYU 2.4.17 */
  240.     MBstat( &out->header.nlen, 1, (long)(BLOCKS(out->dlen)+BLOCKS(out->rlen)) );
  241. #endif                                                            /* BYU 2.4.17 */
  242.  
  243.     if (out->bytes) {
  244.         if ((err=HOpen( out->vrefnum, out->dirID, out->name, fsRdWrPerm, &out->fd)) != noErr) {
  245.             if (err == -43) {
  246.                 long    cre,typ;
  247.                 
  248.                 BlockMove(out->header.type, &typ,  4);
  249.                 BlockMove(out->header.creator, &cre, 4);
  250.  
  251.                 HCreate( out->vrefnum, out->dirID, out->name, cre, typ);
  252.                 if (HOpen(out->vrefnum, out->dirID, out->name, fsRdWrPerm, &out->fd)) 
  253.                     return;
  254.                 }
  255.             else {
  256.                 return;
  257.                 }
  258.             }
  259.         }
  260.     else {
  261.         if ((err=HOpenRF( out->vrefnum, out->dirID, out->name, fsRdWrPerm, &out->fd)) != noErr) {
  262.             if (err == -43) {
  263.                 long    cre,typ;
  264.  
  265.                 BlockMove(out->header.type, &typ, 4);
  266.                 BlockMove(out->header.creator, &cre, 4);
  267.  
  268.                 HCreate( out->vrefnum, out->dirID, out->name, cre, typ);
  269.                 if (HOpenRF( out->vrefnum, out->dirID, out->name, fsRdWrPerm, &out->fd)) 
  270.                     return;
  271.                 }
  272.             else {
  273.                 return;
  274.                 }
  275.             }
  276.         out->fork = 1;
  277.         out->bytes=BLOCKS(out->rlen)*128;
  278.         }
  279. }
  280.  
  281. long MBwrite(
  282.     MBFile *out,
  283.     void *buffer,    /* BYU LSC */
  284.     long size
  285.   )
  286. {
  287.     long    rsize;
  288.     
  289.     if (size < 1)
  290.         return(0);
  291.  
  292.     rsize=size;
  293.  
  294.     if (out->sector1 && (size >= sizeof(struct MBHead)) && (!(out->mode & MB_DISABLE)))  {
  295.         if (isMacBinary((MBHead *) buffer)) {            // WARNING: isMacBinary modifies data
  296.             ProcessMBHead( out, (MBHead *) buffer);
  297.             buffer = (void *)((char *)buffer + 128);
  298.             if ((size-=128) <1)
  299.                 return(rsize);
  300.             }
  301.         }
  302.  
  303.     if (bwrite( out,buffer,size))
  304.         return(-1);
  305.     else
  306.         return( rsize);
  307. }
  308.  
  309. void MBclose( MBFile *out)
  310. {
  311.     HFileParam finfo;
  312.     long fpos;
  313.     
  314.     if (!out->fd) {
  315.         if (out != NULL) DisposPtr((Ptr)out);
  316.         return;
  317.         }
  318.  
  319.     if (!(out->mode & MB_DISABLE) && (out->mode & MB_WRITE)) {
  320.         if (out->fork)
  321.             SetEOF( out->fd, (long) out->rlen);
  322.         else
  323.             SetEOF( out->fd, (long) out->dlen);
  324.  
  325.         FSClose( out->fd);
  326.  
  327.         GetFileInfo( out->vrefnum, out->dirID, out->name, &finfo);
  328.         BlockMove(&out->header.type[0], &finfo.ioFlFndrInfo, sizeof(FInfo));
  329.         BlockMove(&out->header.cdate[0], &finfo.ioFlCrDat, 4);
  330.         BlockMove(&out->header.mdate[0], &finfo.ioFlMdDat, 4);
  331.         finfo.ioFlFndrInfo.fdFlags &= 0xfeff;
  332.         finfo.ioFlFndrInfo.fdFlags |= (out->header.flags2 & 0x00FF);
  333.         finfo.ioFlRLgLen=out->rlen;
  334.         finfo.ioFlLgLen =out->dlen;
  335.     
  336.         SetFileInfo( out->vrefnum, out->dirID, out->name, &finfo);
  337.         }
  338.     else if (out->mode & MB_WRITE) {
  339.         GetFPos( out->fd, &fpos);
  340.         SetEOF(  out->fd,  fpos);
  341.         FSClose( out->fd);
  342.         }
  343.     else
  344.         FSClose( out->fd);
  345.     
  346.     DisposPtr((Ptr) out);                    /* JMB 2.6 -- Nice memory leak, no? */
  347. }
  348.  
  349. long MBread
  350.   (
  351.     MBFile *in,
  352.     void *buffer,
  353.     long size
  354.   )
  355. {
  356.     char            *p;
  357.     long            rsize=size;
  358.     unsigned short    crc;
  359.  
  360.     if (in->fork<0) {
  361.         return(-1);
  362.         }
  363.  
  364.     p = buffer;
  365.     
  366.     if (in->sector1) {
  367.         HFileParam finfo;
  368.  
  369. //        setmem( &in->header, sizeof(MBHead), 0);
  370.         WriteZero((Ptr)&in->header, sizeof(MBHead));
  371.         BlockMove(in->name, &in->header.nlen, (Length(in->name) > 31) ? 32 : (Length(in->name)+1));
  372.         GetFileInfo( in->vrefnum, in->dirID, in->name, &finfo);
  373.         BlockMove(&finfo.ioFlFndrInfo, &in->header.type[0], sizeof(FInfo) );
  374.         in->header.flags2 = finfo.ioFlFndrInfo.fdFlags & 0x00FF;
  375.         in->header.protected = (in->header.zero2 & 0x40)?1:0;
  376.         in->header.zero2 = 0;
  377.         BlockMove(&finfo.ioFlLgLen, &in->header.dflen[0], 4);
  378.         BlockMove(&finfo.ioFlRLgLen, &in->header.rflen[0], 4);
  379.         BlockMove(&finfo.ioFlCrDat, &in->header.cdate[0], 4);
  380.         BlockMove(&finfo.ioFlMdDat, &in->header.mdate[0], 4);
  381.         in->header.mb2versnum = 129;
  382.         in->header.mb2minvers = 129;
  383.         crc = CalculateCRC((unsigned char *) &(in->header), 124, 0);
  384.         BlockMove(&crc, &(in->header.crc), 2);
  385.         
  386.         in->dlen=finfo.ioFlLgLen;
  387.         in->rlen=finfo.ioFlRLgLen;
  388.         
  389.         if (! (in->mode & MB_DISABLE) ) {
  390.             if (size<128) return(-1);
  391.  
  392.             BlockMove(&in->header, p, 128);
  393.             p +=128;
  394.             size -= 128;
  395.             in->bytes= BLOCKS(in->dlen)*128;
  396.             in->binary=1;
  397.             }
  398.         else {
  399.             in->bytes = in->dlen;
  400.             in->rlen=0;
  401.             in->binary=0;
  402.             }
  403.         in->sector1=0;
  404. #if 0                                                            /* BYU 2.4.17 */
  405.         MBstat( &in->header.nlen, 1, (long) (BLOCKS(in->dlen)+BLOCKS(in->rlen)) );
  406. #endif                                                            /* BYU 2.4.17 */
  407.         }
  408.  
  409.     if ( size >0) {
  410.         long length = size;
  411.         OSErr err;
  412.  
  413.         err = FSRead( in->fd, &length, p);
  414.  
  415.         size -= length;
  416.         in->bytes -=length;
  417.         p += length;
  418.  
  419.         if (err == -39 || (in->bytes<=0) ) {
  420.             FSClose( in->fd );
  421.             if (in->bytes<0L) in->bytes=0L;
  422. //            setmem(p, in->bytes, 0);            //    Make filler bytes zero
  423.             WriteZero(p, in->bytes);
  424.             size -= in->bytes;
  425.             p    +=      in->bytes;                /* Make adjustments for necessary 128 byte term */
  426.             if (!in->fork ) {
  427.                 in->fork=1;
  428.                 in->bytes= BLOCKS(in->rlen)*128;
  429.                 if (in->bytes) {
  430.                     HOpenRF( in->vrefnum, in->dirID, in->name, fsRdWrPerm, &in->fd);
  431. #ifdef READ
  432.                     length=(long)size;
  433.                     if (length >0L) {
  434.                         err = FSRead( in->fd, &length, p);
  435.                         size -= length;
  436.                         in->bytes -=length;
  437.                         }
  438. #endif READ
  439.                     }
  440.                 else {
  441.                     in->fd=0;
  442.                     in->fork=-1;                    /* Time to close up shop */
  443.                     }
  444.                 }
  445.             else {
  446.                 in->fd=0;
  447.                 in->fork=-1;                    /* Time to close up shop */
  448.                 }
  449.             }
  450.         }
  451.     return( rsize-size); 
  452. }
  453.  
  454. void init_mb_files(void) {            /* BYU */
  455.   mbfp->fd = 0;                /* BYU */
  456. }                            /* BYU */
  457.                             /* BYU */
  458. void close_mb_files(void) {            /* BYU */
  459.     if (mbfp->fd != 0) MBclose( mbfp );                /* BYU - close input file */
  460. }                            /* BYU */
  461.